﻿var itk_mitemfld = null;
var itk_mitemdir = null;
var itk_mitemctx = null;
var itk_mitemsource = null;
var itk_mitemtarget = null;
var itk_rowsource = null;
var itk_rowtarget = null;
var itk_mitemsourceval = null;
var itk_mitemtargetval = null;

function itk_moveOrder(fldName, itemId, dir, row, totalRows) {
    //Store the current order value of the item being moved
    itk_mitemsourceval = row.find('div[id=itk_moveval_' + itemId + ']')[0].innerHTML;
    
    //Determine whether we are trying to move the first item up or the last item down : this should not be possible
    var bUpdate = false;
    if (dir == 1) {
        //Only allow the item to be moved up the list (lowering the order value) if the current value is greater than 1
        if (itk_mitemsourceval > 1) {
            itk_rowtarget = row.prev();
            bUpdate = true;
        }
    }
    else {
        //Only allow the item to be moved down the list (increasing the order value) if the current value is less than the
        //total number of items in the list
        if (itk_mitemsourceval < totalRows) {
            itk_rowtarget = row.next();
            bUpdate = true;
        }
    }

    //If we determined that the item should not be moved any further then cease execution
    if (!bUpdate) return false;

    //Get the target value that this item will be replacing...we cannot simply increase or decrease the order value by 1
    //in case items have been deleted or we are in a view that filters out items
    itk_mitemtargetval = itk_getHiddenValueDiv(itk_rowtarget).innerHTML;
    //Store other global variables for use in other async callback functions
    itk_rowsource = row;
    itk_mitemfld = fldName;
    itk_mitemdir = dir;
    itk_mitemctx = SP.ClientContext.get_current();

    //Get an object representing the current item being moved (source)
    var sListId = SP.ListOperation.Selection.getSelectedList();
    var oWeb = itk_mitemctx.get_web();
    itk_mitemsource = oWeb.get_lists().getById(sListId).getItemById(itemId);

    var oCaml = new SP.CamlQuery();
    oCaml.set_viewXml('<View><Query><Where><Eq><FieldRef Name=\'' + itk_mitemfld + '\'/>' +
                    '<Value Type=\'Number\'>' + itk_mitemtargetval + '</Value></Eq>' +
                    '</Where></Query><RowLimit>1</RowLimit></View>');
    
    //Get an object representing the item that is affected by the move (target)
    itk_mitemtarget = oWeb.get_lists().getById(sListId).getItems(oCaml);

    itk_mitemctx.load(itk_mitemsource, fldName);
    itk_mitemctx.load(itk_mitemtarget);
    itk_mitemctx.executeQueryAsync(itk_moveOrderItemSuccess, function (sender, args) { SP.UI.Notify.addNotification('Reorder failed: ' + args.get_message(), true); });
}

function itk_moveOrderItemSuccess() {
    //Get hold of the target item and set it's order value to that of the source item
    var oRpItem = itk_mitemtarget.itemAt(0);
    if (oRpItem) {
        oRpItem.set_item(itk_mitemfld, itk_mitemsourceval);
        oRpItem.update();
        itk_mitemctx.load(oRpItem);
    }

    //Set the order value of the source item to it's new value
    itk_mitemsource.set_item(itk_mitemfld, itk_mitemtargetval);
    itk_mitemsource.update();

    itk_mitemctx.load(itk_mitemsource);
    itk_mitemctx.executeQueryAsync(itk_moveCompleteSuccess, function (sender, args) { SP.UI.Notify.addNotification('Refresh failed: ' + args.get_message(), true); });
}

function itk_moveCompleteSuccess() {
    //A hidden <div/> element contains the actual order value of the item in order to facilitate the client side
    //functionality this value must be updated for both source and target items

    //Set the new order value of the source item
    var oDiv = itk_getHiddenValueDiv(itk_rowsource);
    oDiv.innerHTML = itk_mitemtargetval;
    
    //Find the actual <tr/> element of the target item and set the hidden <div/> order value appropriately
    //move the source item's <tr/> element before or after the target item
    if (itk_mitemdir == 1) {
        itk_rowsource.insertBefore(itk_rowtarget);
    } else {
        itk_rowsource.insertAfter(itk_rowtarget);
    }
    itk_getHiddenValueDiv(itk_rowtarget).innerHTML = itk_mitemsourceval;   
}

//Returns the hidden <div/> element that contains the field's actual order value
function itk_getHiddenValueDiv(row) {
    var sSelector = 'div[id^=itk_moveval_]'; //id[starts with]
    var oDiv = $(sSelector, row)[0];
    return oDiv;
}